package cn.lczze.stock.util;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
//import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
public class HttpUtils {

	private static final CloseableHttpClient httpclient = HttpClients.createDefault();

	static String proxyHost;
	static int proxyPort = -1;
	static {
		proxyHost = System.getProperty("proxy.host", null);
		String port = System.getProperty("proxy.port", null);

		if (StringUtils.isNotBlank(proxyHost) && StringUtils.isNotBlank(port)) {
			proxyPort = Integer.parseInt(port.trim());
			System.err.println("proxy ip=".concat(proxyHost));
			System.err.println("proxy port=".concat(port));
		}
	}

	private static HttpURLConnection newConnection(URL realUrl) throws IOException {
		if (StringUtils.isNotBlank(proxyHost) && proxyPort != -1)
			return (HttpURLConnection) realUrl
					.openConnection(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(proxyHost, proxyPort)));
		else
			return (HttpURLConnection) realUrl.openConnection();
	}

	/**
	 * post
	 *
	 * @return
	 */
	public static <T> T postBody(String url, int timeout, Object requestObj, Class<T> responseClass) {
		return request(url, timeout, requestObj, responseClass, null, "POST");
	}

	public static <T> T postBodyWithHeader(String url, int timeout, Object requestObj, Class<T> responseClass,
			Map<String, String> headerMap) {
		return request(url, timeout, requestObj, responseClass, headerMap, "POST");
	}

	public static <T> T deleteBodyWithHeader(String url, int timeout, Object requestObj, Class<T> responseClass,
			Map<String, String> headerMap) {
		return request(url, timeout, requestObj, responseClass, headerMap, "DELETE");
	}

//	public static <T> T postForm(String url, int timeout, String requestObj, Class<T> responseClass) {
//		OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(3, TimeUnit.SECONDS)
//				.readTimeout(timeout, TimeUnit.SECONDS).build();
//		MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
//		RequestBody body = RequestBody.create(mediaType, requestObj);
//		Request request = new Request.Builder().url(url).method("POST", body)
//				.addHeader("User-Agent", "apifox/1.0.0 (https://www.apifox.cn)").build();
//		try {
//			Response response = client.newCall(request).execute();
//			return JSON.parseObject(response.body().string(), responseClass);
//		} catch (IOException e) {
//			log.error("remoting (url=" + url + ") response content invalid(" + requestObj + ").", e);
//		}
//		return null;
//	}

	public static <T> T request(String url, int timeout, Object requestObj, Class<T> responseClass,
			Map<String, String> headerMap, String method) {
		HttpURLConnection connection = null;
		BufferedReader bufferedReader = null;
		try {
			// connection
			URL realUrl = new URL(url);

			connection = newConnection(realUrl);
			// connection setting
			connection.setRequestMethod(method);
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setReadTimeout(timeout * 1000);
			connection.setConnectTimeout(3 * 1000);
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
			connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
			if (headerMap != null) {
				Iterator<Map.Entry<String, String>> entries = headerMap.entrySet().iterator();
				while (entries.hasNext()) {
					Map.Entry<String, String> entry = entries.next();
					connection.setRequestProperty(entry.getKey(), entry.getValue());
				}
			}
			// do connection
			connection.connect();

			// write requestBody
			if (requestObj != null) {
				String requestBody = JSON.toJSONString(requestObj);
				DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
				dataOutputStream.write(requestBody.getBytes("UTF-8"));
				dataOutputStream.flush();
				dataOutputStream.close();
			}

			int statusCode = connection.getResponseCode();
			if (statusCode != 200 && statusCode != 201) {
				log.error("statusCode not 200,is {}", statusCode);
				return null;
			}

			// result
			bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
			StringBuilder result = new StringBuilder();
			String line;
			while ((line = bufferedReader.readLine()) != null) {
				result.append(line);
			}
			String resultJson = result.toString();

			// parse returnT
			try {
				return JSON.parseObject(resultJson, responseClass);
			} catch (Exception e) {
				log.error("remoting (url=" + url + ") response content invalid(" + resultJson + ").", e);
				return null;
			}

		} catch (Exception e) {
			log.error("remoting (url=" + url + ") error", e);
			log.error(e.getMessage(), e);
			return null;
		} finally {
			try {
				if (bufferedReader != null) {
					bufferedReader.close();
				}
				if (connection != null) {
					connection.disconnect();
				}
			} catch (Exception e2) {
				log.error(e2.getMessage(), e2);
			}
		}
	}

	/**
	 * get
	 *
	 * @return
	 */
	public static <T> T getBody(String url, int timeout, Class<T> responseClass) {
		HttpURLConnection connection = null;
		BufferedReader bufferedReader = null;
		try {
			// connection
			URL realUrl = new URL(url);
			connection = newConnection(realUrl);

			// connection setting
			connection.setRequestMethod("GET");
			connection.setDoOutput(false);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setReadTimeout(timeout * 1000);
			connection.setConnectTimeout(3 * 1000);
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
			connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");

			// do connection
			connection.connect();

			// valid StatusCode
			if (connection.getResponseCode() != 200) {
				log.error("statusCode not 200,is {}", connection.getResponseCode());
				return null;
			}

			// result
			bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
			StringBuilder result = new StringBuilder();
			String line;
			while ((line = bufferedReader.readLine()) != null) {
				result.append(line);
			}
			String resultJson = result.toString();

			// parse returnT
			try {
				return JSON.parseObject(resultJson, responseClass);
			} catch (Exception e) {
				log.error("remoting (url=" + url + ") response content invalid(" + resultJson + ").", e);
				return null;
			}

		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return null;
		} finally {
			try {
				if (bufferedReader != null) {
					bufferedReader.close();
				}
				if (connection != null) {
					connection.disconnect();
				}
			} catch (Exception e2) {
				log.error(e2.getMessage(), e2);
			}
		}
	}

	/**
	 * get
	 *
	 * @return
	 */
	public static String getBody(String url, int timeout) {
		HttpURLConnection connection = null;
		BufferedReader bufferedReader = null;
		try {
			// connection
			URL realUrl = new URL(url);
			connection = newConnection(realUrl);
			// connection setting
			connection.setRequestMethod("GET");
			connection.setDoOutput(false);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setReadTimeout(timeout * 1000);
			connection.setConnectTimeout(3 * 1000);
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
			connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");

			// do connection
			connection.connect();

			// valid StatusCode
			if (connection.getResponseCode() != 200) {
				log.error("statusCode not 200,is {}", connection.getResponseCode());
				return null;
			}

			// result
			bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
			StringBuilder result = new StringBuilder();
			String line;
			while ((line = bufferedReader.readLine()) != null) {
				result.append(line.trim()).append(";");
			}
			return result.toString();

		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return null;
		} finally {
			try {
				if (bufferedReader != null) {
					bufferedReader.close();
				}
				if (connection != null) {
					connection.disconnect();
				}
			} catch (Exception e2) {
				log.error(e2.getMessage(), e2);
			}
		}
	}

	/**
	 * 发送HttpGet请求
	 * @param url
	 * @return
	 */
	public static String sendGet(String url) {

		HttpGet httpget = new HttpGet(url);
		CloseableHttpResponse response = null;
		try {
			response = httpclient.execute(httpget);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		String result = null;
		try {
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity);
			}
		} catch (ParseException | IOException e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}


}
